////////////////////////////////////////////////////////////////////////////////
// Filename: Model3DInstance.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _MODEL3DINSTANCE_H_
#define _MODEL3DINSTANCE_H_


//////////////
// INCLUDES //
//////////////

#include <windows.h>
#include <xnamath.h>
#include <vector>
#include "RenderItem.h"
#include "Tools.h"
#include "ModelPostureLink.h"

class Model3D;
class Game;
class Mesh;
class ModelAnimationBoneInstance;
class ModelPostureBone;
class ShadowMap;

struct MeshInstance
{
	Mesh* mMesh;
	XMFLOAT4X4 mTransform;
	XMFLOAT4X4 mLocalTransform;
	XMFLOAT4X4 mFinalTransform;
	RenderItem* mRenderItem;
	MeshInstance* mParentMeshInstance;

	ModelPostureBone* mCurrentPosture;
	ModelPostureBone* mNextPosture;
};

class Model3DInstance
{
public:
	Model3DInstance();
	Model3DInstance(const Model3DInstance&);
	Model3DInstance operator=(Model3DInstance const&);
	~Model3DInstance();

	bool Initialize(Model3D* pModel3d, XMFLOAT3 &pPosition, XMFLOAT4 &pRotation);
	void SetRenderDistance(float pRenderDistanceMin, float pRenderDistanceMax);
	void Uninit();

	void PreRender(float pDistance);
	void RenderMesh(int pMeshIndex);
	void Render();

	void setTransform(const XMFLOAT4X4 &pTranform);
	void CalculLocalTransform(int pMeshIndex);
	void CalculFinalTransform(MeshInstance* pMesh);
	Model3D* GetModel3D();

	void StopRender();

	void GetBoundingBox(BoundingBox &pBoundingBox);

	MeshInstance* GetMeshInstance(int pIndex);

	void ApplyTransformToMesh(int pMeshIndex, const XMFLOAT4X4 &pTransform);

	void SetPosture(std::string pPostureName);
	void SetNextPosture(std::string pPostureName);
	void SetPostureAmount(float pAmount);

	//void ShadowRender(ShadowMap* pShadowMap);

	XMFLOAT4X4 GetTransform();
private:
	Game* mGame;

	Model3D* mModel3d;
	XMFLOAT3 mPosition;
	XMFLOAT4X4 mTransformation;
	float mRenderDistanceMin;
	float mRenderDistanceMax;

	bool mIsRendering;

	int mMeshInstanceCount;
	MeshInstance* mMeshInstances;
	MeshInstance* mMainMesh;

	float mAmount;
};

#endif
